<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript测试</title>
</head>
<body>
    <script>
    var a = 'haha';
    console.log(a.length);
    var b = '哈哈';
    console.log(b.length);
    var a1 = "my name is";
    var b1 = "Gremmie";
    console.log(a1 + b1);
    var a2 = "my score is ";
    var b2 = 100;
    console.log(a2 + b2);

    var a3;
    console.log(a3);

    console.log(a3 + "10");

    console.log(a3 + 10);
    
    var b3 = null;
    console.log(b3 + 10);
    console.log(b3 + "10");

    var num = 10;
    // var num = prompt("请输入你需要判断奇偶的数字");
    if (num % 2 == 0){
        console.log("num是个偶数");
    } else {
        console.log("num是个奇数");
    }

    var num1 = -9;
    // var num1 = prompt("请输入你要判断正负性的数字:");
    if (num1 > 0){
        console.log("num1是正数");
    } else if (num1 < 0) {
        console.log("num1是负数");
    } else {
        console.log("num1是 0");
    }

    //判断闰年
    var year = 2000;
    if (year % 100 == 0){
        if (year % 400 == 0){
            console.log("是闰年");
        } else {
            console.log("不是闰年");
        }
    } else {
        if (year % 4 == 0){
            console.log("是闰年");
        } else {
            console.log("不是闰年");
        }
    }
    var day = 4;
    // var day = prompt("请输入今天星期几: ");
    switch (parseInt(day)) {
        case 1:
            console.log("星期一");
            break;
        case 2:
            console.log("星期二");
            break;
        case 3:
            console.log("星期三");
            break;
        case 4:
            console.log("星期四");
            break;
        case 5:
            console.log("星期五");
            break;
        case 6:
            console.log("星期六");
            break;
        case 7:
            console.log("星期日");
            break;
        default:
            console.log("输入有误");
}
    // var num = 1;
    // while (num <= 10) {
    //     console.log(num);
    //     num++;
    // }

    //创建数组的方法,其中new Array中的A记得大写
    var arr1 = new Array();
    var arr2 = [];

    var arr = ['小猪佩奇', '小猪乔治', '小羊苏西'];
    //JS 的数组不要求元素是相同类型
    console.log(arr);
    console.log(arr[0]);
    console.log(arr[1]);
    console.log(arr[2]);
    arr[2] = '小猫凯迪';
    console.log(arr);

    //1.相当于在末尾新增元素. 新增的元素默认值为 undefined
    var arr1 = [9, 5, 2, 7];
    arr1.length = 6;
    console.log(arr1);
    console.log(arr1[4], arr1[5]);

    //2.通过下标新增元素
    //如果下标超出范围赋值元素, 则会给指定位置插入新元素
    var arr2 = [];
    arr2[2] = 10;
    console.log(arr2);    
    //此时这个数组的 [0] 和 [1] 都是 undefined

    //3.使用push进行追加元素
    //给定一个数组,把数组中的奇数放到一个newArr中
    var arr3 = [9, 5, 2, 7, 3, 6, 8];
    var newArr = [];
    for (var i = 0; i < arr.length; i++) {
        if (arr3[i] % 2 != 0) {
            newArr.push(arr3[i]);
        }
    }
    console.log(newArr);


    //删除数组中的元素
    //使用splice方法删除元素
    var arr4 = [9, 5, 2, 7];
    console.log(arr4);
    //第一个参数表示从下标为2的位置开始删除,
    //第二个参数表示要删除的元素个数是1个
    arr4.splice(2, 1); 
    console.log(arr4);

    function hello(){
        console.log("hello~");
    }
    //如果不调用函数,则没有执行打印语句
    //调用函数的时候进入函数内部执行, 
    //函数结束时回到调用位置继续执行. 
    //可以借助调试器来观察.
    hello();
    //函数的定义和调用的先后顺序没有要求. 
    //(这一点和变量不同, 变量必须先定义再使用)

    //关于参数的个数
    //实参和形参之间的个数可以不匹配. 
    //但是实际开发一般要求形参和实参个数要匹配
    //1)如果实参个数比形参个数多,则多出来的参数不参与函数的运算
    function sum (a, b) {
        return a + b;
    }
    console.log(sum(10,20,30));//30
    //2)如果实参个数比形参个数少,
    //则此时多出来的形参值为undefined
    console.log(sum(10));//NaN,相当于num2号位为undefined

    //函数表达式
    //另外一种函数的定义方式
    var add = function(){
        var sum = 0;
        for (var i = 0;i < arguments.length; i++){
            sum += arguments[i];
        }
        return sum; 
    }
    //这里的arguments数组就是你输进去的数字
    console.log(add(1));//1
    console.log(add(1, 2));//3
    console.log(add(1, 2, 3));//6
    console.log(add(1, 2, 3, 4));//10
    
    //JavaScript中也有全局变量和局部变量
    //创建变量时如果不写var,那么将会得到一个全局变量
    var num = 99;
    function test(){
        num = 100;
    }
    test();
    console.log(num);//100


    //作用域链
    //函数可以嵌套定义,不像C语言
    //内层函数可以访问到外层函数的局部变量
    //内部函数通过链式查找的方式,
    //从内向外得依次查找.
    //先找自己函数里有没有,没有得话再出去找
    var num = 1;
    function test1(){
        var num = 10;

        function test2(){
            var num = 20;
            console.log(num);
        }
        test2();
    }
    test1();//20
    
    //对象
    //1.使用字面量创建对象[常用]
    //使用{}创建对象
    var x = {}; //创建了一个空的对象

    var student = {
        name : '葛玉礼',
        height : 186,
        weight : 145,
        sayHello : function(){
            console.log("What's up bro");
        }
    };
    //使用{}创建对象
    //属性和方法使用键值对的形式来组织
    //键值对之间使用逗号来分割,最后一个属性后面的逗号可有可无
    //键和值之间使用分号来分割
    //方法的值是一个匿名的函数

    //使用对象的属性和方法
    //1)使用点'.'(即成员访问运算符来访问属性`.`->`的`)
    console.log(student.name);
    //2)使用[]访问属性,此时属性需要加上引号
    console.log(student['height']);
    //3)调用方法,别忘记啊加上()
    student.sayHello();//What's up bro

    //2.使用new Object创建对象
    var student1 = new Object(); // 和创建数组类似
    student.name = "蔡徐坤";
    student.height = 175;
    student['weight'] = 170;
    student.sayHello = function () {
        console.log("hello");
    }
    console.log(student.name);
    console.log(student['weight']);
    student.sayHello();

    //3.使用构造函数创建对象
    //前面的创建对象方式只能创建一个对象,而使用构造函数可以很方便得创建多个对象
    //比如下面我们创建几个猫咪对象

    var mini = {
        name: "咪咪",
        type:"中华田园喵",
        miao: function () {
            console.log("喵");
        }
    }
    var xiaoHei = {
        name: "小黑",
        type: "波斯喵",
        miao: function () {
            console.log("喵呜");
        }
    }
    var ciQiu = {
        name: "刺球",
        type: "金渐层",
        miao: function () {
            console.log("咕噜噜");
        }
    }
    //以上的代码写起来就很麻烦
    //我们可以使用构造函数,
    //把相同的属性和方法的创建提取出来,简化开发过程

    /*
    在构造函数内部使用This关键字来表示当前正在构建的对象
    构造函数的函数名首字母一般是大写的
    构造函数的函数名可以是名词
    构造函数不需要return
    创建对象的时候必须使用new关键字
    this可以看作'我'
    */
   //我们使用构造函数重新创建猫咪对象
   function Cat(name, type, sound) {
    this.name = name;
    this.type = type;
    this.miao = function () {
        console.log(sound);//不要忘记作用域的链式访问规则
    }
   }
   var mimi = new Cat('咪咪','中华田园喵','喵');
   var xiaoHei = new Cat('小黑','波斯喵','喵呜');
   var ciQiu = new Cat('刺球','金渐层','咕噜噜');
   console.log(mimi);
   mimi.miao();

   //理解new关键字
   /*
   new的执行过程
    1.现在内存中创建一个空的对象{}
    2.this指向刚才的空对象
    3.执行构造函数的代码,给对象创建属性和方法
    4.返回这个对象(构造函数本身不需要return,由new 代劳了) 
    */

   /*
   1. Javascript中没有类的概念
   2. JavaScript对象不区分"属性"和"方法"
   3. javaScript对象中没有private/public等访问控制机制
   4. JavaScript对象没有继承
    (JavaScript中使用"原型"机制实现类似的效果)
   */
   var animal = {
    eat: function () {
        console.log("吃东西");
    }
   }
   var dog = {
    name: "dog",
    __proto__: animal //指向animal对象
   };

   var cat = {
    name: "cat",
    __proto__: animal //指向animal对象
   }

   dog.eat(); 
   cat.eat();

   /*当eat方法被调用的时候，先在自己的方法列表中寻找， 
    如果找不到，就去找原型中的方法， 如果原型
    中找不到， 就去原型的原型中去寻找...... 
    最后找到Object那里， 如果还找不到， 
    那就是未定义了。
    */
    //另外,JavaScript中没有多态

    </script>
</body>
</html>